package com.huangd.platform.modules.sys.service.impl;


import com.huangd.platform.config.GlobalConfig;
import com.huangd.platform.modules.sys.form.FileForm;
import com.huangd.platform.common.exception.RRException;
import com.huangd.platform.common.utils.DateUtils;
import com.huangd.platform.common.utils.FileUtils;
import com.huangd.platform.common.utils.R;
import com.huangd.platform.common.utils.ZipUtils;
import com.huangd.platform.modules.sys.service.SysFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @author huangd
 */
@Service("sysFileService")
@Slf4j
public class SysFileServiceImpl implements SysFileService {

    @Override
    public R list(HttpServletResponse response, String uri, String sort_by, String sort) {


        String dir = GlobalConfig.DATA_FILE_SYSTEM;
        log.info(dir);

        uri = uri == null ? "" : uri;
        //uri = new String(uri.getBytes("iso8859-1"));

        File file = new File(dir, uri);

        if (!file.exists())
            return R.error("文件不存在");
        FileForm parentInfo = null;
        List<FileForm> fileinfos = new ArrayList<>();
        try {
            if (file.isFile()) {
                String filename = new String(file.getName().getBytes(), "iso8859-1");
                response.setCharacterEncoding("utf-8");
                response.setContentType("multipart/form-data");
                response.setHeader("Content-Disposition", "attachment;fileName=" + filename);

                InputStream is = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                byte[] b = new byte[4096];
                int length;
                while ((length = is.read(b)) > 0) {
                    os.write(b, 0, length);
                }
                is.close();
                return null;
            }

            if (!uri.isEmpty()) {
                File parent = file.getParentFile();

                parentInfo = new FileForm();
                parentInfo.setName("..");
                int index = uri.lastIndexOf("/", uri.length() - 2);
                parentInfo.setUrl(index == -1 ? "" : uri.substring(0, index + 1));
                parentInfo.setLastModifyTime(DateUtils.date2String(new Date(parent.lastModified()), DateUtils.PATTERN_DATE_TIME));
                parentInfo.setSize(FileUtils.getFormatSize(parent.length()) + "(" + parent.length() + "B)");
                parentInfo.setDir(parent.isDirectory());
            }

            for (File f : file.listFiles()) {
                FileForm info = new FileForm();
                info.setName(f.getName());

                if (f.isFile())
                    info.setUrl(uri + f.getName());
                else
                    info.setUrl(uri + f.getName() + "/");

                info.setLastModifyTime(DateUtils.date2String(new Date(f.lastModified()), DateUtils.PATTERN_DATE_TIME));
                info.setSize(FileUtils.getFormatSize(f.length()) + "(" + f.length() + "B)");
                info.setDir(f.isDirectory());
                fileinfos.add(info);
            }

            final int desc = sort != null && sort.equals("desc") ? -1 : 1;

            if (sort_by != null && sort_by.equals("lastModifyTime")) {
                fileinfos.sort((o1, o2) -> {
                    Date d1 = DateUtils.string2Date(o1.getLastModifyTime(), DateUtils.PATTERN_DATE_TIME);
                    Date d2 = DateUtils.string2Date(o2.getLastModifyTime(), DateUtils.PATTERN_DATE_TIME);
                    return desc * d1.compareTo(d2);
                });
            } else {
                fileinfos.sort((o1, o2) -> desc * o1.getName().compareTo(o2.getName()));
            }

            if (parentInfo != null) {
                fileinfos.add(0, parentInfo);
            }
            return R.ok(fileinfos);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error();
        }

    }

    @Override
    public R upload(MultipartFile upload, String uri, int incType) {
        try {
            String dir = GlobalConfig.DATA_FILE_SYSTEM;
            File file = new File(dir, uri);
            File createFile = new File(file, upload.getOriginalFilename());

            //文件检测
            if (createFile.exists())
                return R.error("目标文件已经存在");

            //保存zip文件
            upload.transferTo(createFile);

            if (incType == 1) {
                //解压到当前目录
                ZipUtils.unzip(createFile, file);
                //删除该压缩文件
                createFile.delete();
            }
            return R.ok();

        } catch (Exception e) {
            e.printStackTrace();
            return R.error("上传失败");
        }
    }

    @Override
    public R clear(String uri, String path) {

        try {
            String dir = GlobalConfig.DATA_FILE_SYSTEM;
            File file = new File(dir, path);

            //目标文件不存在
            if (!file.exists()) {

                return R.error("文件不存在");
            }

            if (file.isFile())
                return R.error("只能对目录进行清空操作");


            //清空
            org.apache.commons.io.FileUtils.cleanDirectory(file);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("清理失败");
        }
        return R.ok();
    }

    @Override
    public R delete(String path) {

        try {
            String dir = GlobalConfig.DATA_FILE_SYSTEM;
            File file = new File(dir, path);

            if (file.exists()) {
                //删除
                if (file.isFile())
                    file.delete();
                else
                    org.apache.commons.io.FileUtils.deleteDirectory(file);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("删除失败");
        }
        return R.ok();
    }

    @Override
    public Boolean dowload(HttpServletResponse response, String dir, String filename) {
        File dirFile = new File(GlobalConfig.DATA_WEB_EXCEL_DATA, dir);
        if (!dirFile.exists())
            dirFile.mkdirs();

        File file = new File(dirFile, filename);

        File tmpDir = new File(GlobalConfig.DATA_WEB_EXCEL_DATA, "tmp");
        tmpDir = new File(tmpDir, dir);
        File tmpfile = new File(tmpDir, filename);

        if (file.exists()) {
            try {
                if (tmpfile.exists())
                    tmpfile.delete();

                filename = URLEncoder.encode(filename, "UTF-8");

                if (response != null) {
                    byte[] bytes = org.apache.commons.io.FileUtils.readFileToByteArray(file);
                    response.setContentType("application/vnd.ms-excel");
                    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                    response.setHeader("Content-Disposition", "attachment;filename=" + filename);
                    response.getOutputStream().write(bytes);
                }
            } catch (Exception e) {
                throw new RRException(e.getMessage());
            }

            return true;
        } else {
            if (tmpfile.exists())
                throw new RRException("数据已经在查询中");

            try {
                if (!tmpDir.exists())
                    tmpDir.mkdirs();

                tmpfile.createNewFile();
            } catch (Exception e) {
                throw new RRException(e.getMessage());
            }
        }

        return false;
    }
}
